package com.imooc.service.impl;

import com.imooc.common.constants.ResultCodeConstants;
import com.imooc.common.enums.YesOrNo;
import com.imooc.common.utils.ExceptionProcessorUtils;
import com.imooc.converter.AddressConverter;
import com.imooc.dto.address.*;
import com.imooc.mapper.UserAddressMapper;
import com.imooc.pojo.UserAddress;
import com.imooc.service.IAddressService;
import lombok.extern.slf4j.Slf4j;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * @ClassName: AddressServiceImpl
 * @Description: 地址相关 Service 实现
 * @author: limingxing
 * @Date: 2019-12-26 11:18
 */
@Slf4j
@Service
public class AddressServiceImpl implements IAddressService {
    @Autowired
    private UserAddressMapper addressMapper;
    @Autowired
    private AddressConverter addressConverter;

    @Autowired
    private Sid sid;

    @Override
    public AddAddressResponse createAddress(AddAddressRequest request) {
        log.info("Begin AddressServiceImpl.createAddress request: [{}]", request);
        request.requestCheck();
        AddAddressResponse response = new AddAddressResponse();
        try {
            Integer isDefault = 0;
            // 1. 判断当前用户是否存在地址，如果没有，则新增为‘默认地址’
            List<UserAddress> addressList = getDefaultAddress(request.getUserId());
            if (addressList == null || addressList.isEmpty() || addressList.size() == 0) {
                isDefault = 1;
            }

            // 2. 保存地址到数据库
            UserAddress address = addressConverter.req2Address(request);

            address.setId(sid.nextShort());
            address.setIsDefault(isDefault);
            address.setCreatedTime(new Date());
            address.setUpdatedTime(new Date());
            Integer row = addressMapper.insert(address);
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
            log.info("AddressServiceImpl.createAddress effect row : [{}]", row);

        } catch (Exception e) {
            log.error("AddressServiceImpl.createAddress occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public DeleteAddressResponse deleteAddress(DeleteAddressRequest request) {
        log.info("Begin AddressServiceImpl.deleteAddress request: [{}]", request);
        request.requestCheck();
        DeleteAddressResponse response = new DeleteAddressResponse();
        try{
            UserAddress address = new UserAddress();
            address.setId(request.getAddressId());
            address.setUserId(request.getUserId());
            Integer result =  addressMapper.delete(address);
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
            log.info("AddressServiceImpl.deleteAddress effect result : [{}}]", result);
        }catch (Exception e){
            log.error("AddressServiceImpl.deleteAddress occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UpdateAddressResponse updateAddress(UpdateAddressRequest request) {
        log.info("Begin AddressServiceImpl.updateAddress request: [{}]", request);
        request.requestCheck();
        UpdateAddressResponse response = new UpdateAddressResponse();
        try{
            UserAddress pendingAddress = new UserAddress();
            BeanUtils.copyProperties(request, pendingAddress);
            pendingAddress.setId(request.getAddressId());
            pendingAddress.setUpdatedTime(new Date());
            Integer result = addressMapper.updateByPrimaryKeySelective(pendingAddress);
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
            log.info("AddressServiceImpl.updateAddress effect result : [{}}]", result);
        }catch (Exception e){
            log.error("AddressServiceImpl.updateAddress occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public UpdateAddressResponse updateAddressToBeDefault(UpdateAddressDefaultRequest request) {
        log.info("Begin AddressServiceImpl.updateAddressToBeDefault request: [{}]", request);
        request.requestCheck();
        UpdateAddressResponse response = new UpdateAddressResponse();
        try{
            List<UserAddress> addressList = getDefaultAddress(request.getUserId());
            for (UserAddress address : addressList) {
                address.setIsDefault(YesOrNo.NO.type);
                addressMapper.updateByPrimaryKeySelective(address);
            }
            // 2. 根据地址id修改为默认的地址
            UserAddress defaultAddress = new UserAddress();
            defaultAddress.setId(request.getAddressId());
            defaultAddress.setUserId(request.getUserId());
            defaultAddress.setIsDefault(YesOrNo.YES.type);
            Integer row = addressMapper.updateByPrimaryKeySelective(defaultAddress);
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            log.info("AddressServiceImpl.updateAddressToBeDefault effect row : [{}]", row);
        }catch (Exception e){
            log.error("AddressServiceImpl.updateAddressToBeDefault occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }


    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public AddressListResponse getAddressList(AddressListRequest request) {
        log.info("Begin AddressServiceImpl.getAddressList request: [{}]", request);
        AddressListResponse response = new AddressListResponse();
        try {
            request.requestCheck();
            UserAddress ua = new UserAddress();
            ua.setUserId(request.getUserId());

            List<UserAddress> list = addressMapper.select(ua);
            List<AddressDto> addressDtoList = addressConverter.address2List(list);
            response.setAddressDtoList(addressDtoList);
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
        } catch (Exception e) {
            log.error("AddressServiceImpl.getAddressList occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public QueryAddresResponse queryAddres(QueryAddresRequest request) {
        log.info("Begin AddressServiceImpl.queryAddres request: [{}]", request);
        request.requestCheck();
        QueryAddresResponse response = new QueryAddresResponse();
        try{
            UserAddress singleAddress = new UserAddress();
            singleAddress.setId(request.getAddressId());
            singleAddress.setUserId(request.getUserId());
            UserAddress userAddress = addressMapper.selectOne(singleAddress);
            AddressDto addressDto = addressConverter.address2Dto(userAddress);
            response.setAddress(addressDto);
            response.setMsg(ResultCodeConstants.SUCCESS.getMessage());
            response.setCode(ResultCodeConstants.SUCCESS.getCode());
        }catch (Exception e){
            log.error("AddressServiceImpl.queryAddres occur Exception : [{}]", e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    /**
     * 获取用户默认地址
     * @param userId
     */
    private List<UserAddress> getDefaultAddress(String userId) {
        log.info("AddressServiceImpl.getDefaultAddress userId: [{}]",userId);
        Example example = new Example(UserAddress.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andEqualTo("isDefault", 1);
        List<UserAddress> addressList = addressMapper.selectByExample(example);
        return addressList;
    }
}
